package com.wongoing.util;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;

import org.springframework.web.multipart.MultipartFile;

import com.wongoing.bus.util.SequenceBuilder;
import com.wongoing.sys.shiro.ShiroUser;
import com.wongoing.sys.viewmodel.JsonResult;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import net.coobird.thumbnailator.Thumbnails.Builder;

public class ImageUtil {

	private static ImageUtil instance;
	
	/**
	 * 定义私有构造方法实现单例
	 */
	public ImageUtil() {
		super();
	}

	public synchronized static ImageUtil getInstance() {
		if(instance == null) {
			instance = new ImageUtil();
		}
		return instance;
	}
	/**
	 * 功能说明：上传图片方法
	 * 修改说明：
	 * @author 吴兆强
	 * @date 2017年10月26日 下午8:35:54
	 * @param file
	 * @return
	 */
	public Map<String,Object> uploadImg(String oldPath,String dir,MultipartFile file) {
		Map<String,Object> jsonResult = new HashMap<String, Object>();
		String msg = "";
		try {
			String fileName = file.getOriginalFilename();
			long fileSize = file.getSize();
			String exts = fileName.substring(fileName.lastIndexOf(".") + 1);
			if (fileSize > ResourceUtil.getUploadImageMaxSize()) {
				msg = "上传图片应小于" + (ResourceUtil.getUploadImageMaxSize()/(1024*1024)) + "MB!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).info("『功能：存储图片』失败 ,msg:" + msg);
				return jsonResult;
			}
			if (exts.indexOf(ResourceUtil.getUploadImageExts()) != -1) {
				msg = "上传格式应属于：" + ResourceUtil.getUploadImageExts();
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).info("『功能：存储图片』 ,msg:" + msg);
				return jsonResult;
			}
			//图片命名规则：
			fileName = dir + "_" + DateConvert.formatDateToString(new Date(), DateStyle.YYYYMMDDHHMMSS)+"."+exts;
//			ShiroUser shiroUser = SubjectUtil.getCurrentUser();
//			Integer userId = shiroUser.getUserId();
//			String loginType = shiroUser.getUserType();
//			fileName = dir +"_"+loginType+userId+imgName+"."+exts;
			String path = dir + File.separator + fileName;
			oldPath = (oldPath==null|| oldPath=="")?"upload\\img\\tmp\\tmp_20171205085200.jpg":oldPath;
			oldPath =  ResourceUtil.getUploadImageProjectRoot() + oldPath;
			// 存储路径
			String dirPath = ResourceUtil.getUploadImageRelativeRoot() + dir;
			String filePath = ResourceUtil.getUploadImageRelativeRoot() + path;
			LogService.getInstance(this).debug(filePath);
			//删除原文件
			//防止误传地址误删信息
			if(oldPath.contains("upload")) {
				if (FileUtil.isExists(oldPath)) {
					FileUtil.delete(oldPath);
				}
			}
			//创建新的文件
			boolean resultDir = FileUtil.makedir(dirPath);
			if (resultDir == true) {
				File targetFile = new File(filePath);  
				file.transferTo(targetFile);
				jsonResult = JsonResult.jsonWsReturn(0, ResourceUtil.getUploadImgRelativeRoot()+path ,true);
				LogService.getInstance(this).info("『功能：储存图片』: ,fileName:"
						+ fileName + " ,msg:" + msg);
			} else {
				msg = "建立文件夹" + dir + "失败!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).error("建立文件夹" + dir + "失败，完整路径为：dirPath");
			}
		} catch (Exception e) {
			msg = "上传图片失败!";
			jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
			LogService.getInstance(this).error("上传图片失败",e);
		}
		return jsonResult;
	}
	/**
	 * 功能说明：上传图片方法
	 * 修改说明：
	 * @author 吴兆强
	 * @date 2017年10月26日 下午8:35:54
	 * @param file
	 * @return
	 */
	public Map<String,Object> uploadImg(String loginType, Integer userId,String imgName, String dir, MultipartFile file) {
		Map<String,Object> jsonResult = new HashMap<String, Object>();
		String msg = "";
		try {
			String fileName = file.getOriginalFilename();
			long fileSize = file.getSize();
			String exts = fileName.substring(fileName.lastIndexOf(".") + 1);
			if (fileSize > ResourceUtil.getUploadImageMaxSize()) {
				msg = "上传图片应小于" + (ResourceUtil.getUploadImageMaxSize()/(1024*1024)) + "MB!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).info("『功能：存储图片』失败 ,msg:" + msg);
				return jsonResult;
			}
			if (exts.indexOf(ResourceUtil.getUploadImageExts()) != -1) {
				msg = "上传格式应属于：" + ResourceUtil.getUploadImageExts();
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).info("『功能：存储图片』 ,msg:" + msg);
				return jsonResult;
			}
			//图片命名规则：
			fileName = dir + "_" + DateConvert.formatDateToString(new Date(), DateStyle.YYYYMMDDHHMMSS)+"."+exts;
			//fileName = dir +"_"+loginType+userId+imgName+"."+exts;
			String path = dir + File.separator + fileName;
			// 存储路径
			String dirPath = ResourceUtil.getUploadImageRelativeRoot() + dir;
			String filePath = ResourceUtil.getUploadImageRelativeRoot() + path;
			LogService.getInstance(this).debug(filePath);
			//删除原文件
			if (FileUtil.isExists(filePath)) {
				FileUtil.delete(filePath);
			}
			//创建新的文件
			boolean resultDir = FileUtil.makedir(dirPath);
			if (resultDir == true) {
				File targetFile = new File(filePath);  
				file.transferTo(targetFile);
				jsonResult = JsonResult.jsonWsReturn(0, ResourceUtil.getUploadImgRelativeRoot()+path ,true);
				LogService.getInstance(this).info("『功能：储存图片』: ,fileName:"
						+ fileName + " ,msg:" + msg);
			} else {
				msg = "建立文件夹" + dir + "失败!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).error("建立文件夹" + dir + "失败，完整路径为：dirPath");
			}
		} catch (Exception e) {
			msg = "上传图片失败!";
			jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
			LogService.getInstance(this).error("上传图片失败",e);
		}
		return jsonResult;
	}
	/**
	 * 功能说明：上传裁剪图片，后缀为blob，默认改为png
	 * 修改说明：
	 * @author 吴兆强
	 * @date 2017年10月26日 下午8:35:54
	 * @param file
	 * @return
	 */
	public Map<String,Object> uploadCutImg(String dir,MultipartFile file) {
		Map<String,Object> jsonResult = new HashMap<String, Object>();
		String msg = "";
		try {
			String fileName = file.getOriginalFilename();
			long fileSize = file.getSize();
			String exts = "png";
			if (fileSize > ResourceUtil.getUploadImageMaxSize()) {
				msg = "上传图片应小于2MB!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).info("『功能：存储图片』失败 ,msg:" + msg);
				return jsonResult;
			}
			if (exts.indexOf(ResourceUtil.getUploadImageExts()) != -1) {
				msg = "上传格式应属于：" + ResourceUtil.getUploadImageExts();
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).info("『功能：存储图片』 ,msg:" + msg);
				return jsonResult;
			}
			//图片命名规则：
			fileName = dir + "_" + DateConvert.formatDateToString(new Date(), DateStyle.YYYYMMDDHHMMSS)+"."+exts;
			String path = dir + File.separator + fileName;
			// 存储路径
			String dirPath = ResourceUtil.getUploadImageRelativeRoot() + dir;
			String filePath = ResourceUtil.getUploadImageRelativeRoot() + path;
			LogService.getInstance(this).debug(filePath);
			boolean resultDir = FileUtil.makedir(dirPath);
			if (resultDir == true) {
				File targetFile = new File(filePath);  
				file.transferTo(targetFile);
				jsonResult = JsonResult.jsonWsReturn(0, ResourceUtil.getUploadImgRelativeRoot()+path ,true);
				LogService.getInstance(this).info("『功能：储存图片』: ,fileName:"
						+ fileName + " ,msg:" + msg);
			} else {
				msg = "建立文件夹" + dir + "失败!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).error("建立文件夹" + dir + "失败，完整路径为：dirPath");
			}
		} catch (Exception e) {
			msg = "上传图片失败!";
			jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
			LogService.getInstance(this).error("上传图片失败",e);
		}
		return jsonResult;
	}
	
	/**
	 * 功能说明：上传图片方法（重载）
	 * 修改说明： 同时上传多张图片时，需要标识不同文件，以防覆盖
	 * @author 吴兆强
	 * @date 2017年10月26日 下午8:35:54
	 * @param file
	 * @return
	 */
	public Map<String,Object> uploadImg(String oldPath,String dir,MultipartFile file,String num) {
		Map<String,Object> jsonResult = new HashMap<String, Object>();
		String msg = "";
		try {
			String fileName = file.getOriginalFilename();
			long fileSize = file.getSize();
			String exts = fileName.substring(fileName.lastIndexOf(".") + 1);
			if (fileSize > ResourceUtil.getUploadImageMaxSize()) {
				msg = "上传图片应小于2MB!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).info("『功能：存储图片』失败 ,msg:" + msg);
				return jsonResult;
			}
			if (exts.indexOf(ResourceUtil.getUploadImageExts()) != -1) {
				msg = "上传格式应属于：" + ResourceUtil.getUploadImageExts();
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).info("『功能：存储图片』 ,msg:" + msg);
				return jsonResult;
			}
			//图片命名规则：
			fileName = dir + "_" + DateConvert.formatDateToString(new Date(), DateStyle.YYYYMMDDHHMMSS)+SequenceBuilder.getInstance().getRandomCode(6)+num+"."+exts;
			String path = dir + File.separator + fileName;
			oldPath = (oldPath==null|| oldPath=="")?"upload\\img\\tmp\\tmp_20171205085200.jpg":oldPath;
			oldPath =  ResourceUtil.getUploadImageProjectRoot() + oldPath;
			//删除原文件
			//防止误传地址误删信息
			if(oldPath.contains("upload")) {
				if (FileUtil.isExists(oldPath)) {
					FileUtil.delete(oldPath);
				}
			}
			// 存储路径
			String dirPath = ResourceUtil.getUploadImageRelativeRoot() + dir;
			String filePath = ResourceUtil.getUploadImageRelativeRoot() + path;
			LogService.getInstance(this).debug(filePath);
			boolean resultDir = FileUtil.makedir(dirPath);
			if (resultDir == true) {
				File targetFile = new File(filePath);  
				file.transferTo(targetFile);
				jsonResult = JsonResult.jsonWsReturn(0, ResourceUtil.getUploadImgRelativeRoot()+path ,true);
				LogService.getInstance(this).info("『功能：储存图片』: ,fileName:"
						+ fileName + " ,msg:" + msg);
			} else {
				msg = "建立文件夹" + dir + "失败!";
				jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
				LogService.getInstance(this).error("建立文件夹" + dir + "失败，完整路径为：dirPath");
			}
		} catch (Exception e) {
			msg = "上传图片失败!";
			jsonResult = JsonResult.jsonWsReturn(1, msg ,false);
			LogService.getInstance(this).error("上传图片失败",e);
		}
		return jsonResult;
	}
	
	
	public void thumbnail(String sourceFile, String targetFile, int targetWidth, int targetHeight) {
		 File fromFile = new File(sourceFile);
		          BufferedImage srcImage = null;
		          int s_height = 0;
		          int s_width = 0;
		          try {
		              srcImage = ImageIO.read(fromFile);
		              // 获取源文件的宽高
		              s_height = srcImage.getHeight();
		             s_width = srcImage.getWidth(); 
		              System.out.println(s_height + "");
		              System.out.println(s_width + "");
		          } catch (IOException e1) {
		              e1.printStackTrace();
		          }
		          // 判断是否需要压缩
		          if (targetWidth != s_width || targetHeight != s_height) {// 需要压缩
		              BigDecimal n = new BigDecimal(s_height).divide(new BigDecimal(s_width), 10, BigDecimal.ROUND_UP);// 源图片文件高/宽  的比例
		              BigDecimal m = new BigDecimal(targetHeight).divide(new BigDecimal(targetWidth), 10, BigDecimal.ROUND_UP);// 目标图片文件高/宽 的比例
		              System.out.println(n+ "");
		              System.out.println(m+ "");
		              int flag = n.compareTo(m); //比较源图片文件和目标图片 的高/宽 比
		              try {
		                  if (flag == 0) {// n == m，高/宽 比一致, 无需裁减, 直接压缩
		                      System.out.println("flag： " + flag);
		                      Thumbnails.of(sourceFile).forceSize(targetWidth, targetHeight).toFile(targetFile);
		                } else { // 高/宽 比不一致，需要裁减
		                      if (flag > 0) {// 高的比例 > 宽的比例，以宽的比例进行缩放， 需要裁减高
		                          srcImage = Thumbnails.of(sourceFile).width(targetWidth).asBufferedImage();//以宽的比例进行缩放
		                     } else if (flag < 0) {// n < m 高的比例 < 宽的比例，以高的比例进行缩放， 需要裁减宽
		                          srcImage = Thumbnails.of(sourceFile).height(targetHeight).asBufferedImage();//以高的比例进行缩放
		                      }
		                      // 居中裁减
		                     Builder<BufferedImage> builder = Thumbnails.of(srcImage)
		                              .sourceRegion(Positions.CENTER, targetWidth, targetHeight).size(targetWidth, targetHeight);
		                      builder.toFile(targetFile);
		                  }
		             } catch (IOException e) {
		                  // TODO Auto-generated catch block
		                  e.printStackTrace();
		              }
		          }
	}
	
	/**
	 * 功能说明：上传base64图片的方法
	 * 修改说明：
	 * @author 吴兆强
	 * @date 2017年12月23日 下午3:56:26
	 * @param dir
	 * @param base64
	 * @return
	 */
	public String baseUploadImg(String dir, String base64) {
		OutputStream out = null;
		String path = null;
		String filePath = null;
		try {
			if ("".equals(base64)) {
				return null;
			}
			base64 = base64.substring(base64.indexOf(",") + 1);
			byte[] b = Base64.decode(base64);
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {// 调整异常数据
					b[i] += 256;
				}
			}
			String fileName = dir + "_" + new Random().nextInt()
					+ DateConvert.formatDateToString(new Date(), DateStyle.YYYYMMDDHHMMSS) + ".png";
			path = dir + File.separator + fileName;
			// 存储路径
			String dirPath = ResourceUtil.getUploadImageRelativeRoot() + dir;
			filePath = ResourceUtil.getUploadImageRelativeRoot() + path;
			// 创建新的文件
			boolean resultDir = FileUtil.makedir(dirPath);
			if (resultDir == true) {
				LogService.getInstance(this).debug(filePath);
				File file = new File(filePath);
				out = new FileOutputStream(file);
				out.write(b);
				out.flush();
				out.close();
			} else {
				LogService.getInstance(this).error("建立文件夹" + dir + "失败，完整路径为：dirPath");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ResourceUtil.getUploadImgRelativeRoot()+path;
	}
	/**
	 * 功能说明：压缩图片的方法
	 * 修改说明：
	 * @author 赵希浩
	 * @date 2018年2月1日 下午3:56:26
	 * @param imagePath
	 * @return
	 */
	public void  CompressImg(File image) {
		double sca =0f;
		if(image.length() > 1024*1024) {
			sca = 100f/(image.length()/1024f);
		}else {
			sca = 1;
		}
		System.out.println("file name :" + image.getName() + "      file size :" + image.length()/1024f + "      sca =" + sca);
		try {
			Thumbnails.of(image.getPath()) 
			.scale(sca) 
			.outputQuality(1f) 
			.toFile(image);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		}
	
	/**
	 * 功能说明：删除图片操作
	 * 修改说明：
	 * @author 吴兆强
	 * @date 2018年4月9日 上午10:26:51
	 * @param filePath
	 * @return
	 */
	public boolean deleteImage(String filePath) {
		if (FileUtil.isExists(filePath)) {
			return FileUtil.delete(filePath);
		}
		return true;
	}
}
